﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Xml.Linq;
using System.Xml.XPath;
using SharePointContentGenerator.ContentGeneratorLogic.SharePointWebServiceLists;

namespace SharePointContentGenerator.ContentGeneratorLogic.ContentGenerators
{
    internal class SharePointLibraryController : SharePointController
    {
        internal virtual void LibraryCreated(string libraryName, int libraryIndex) {}
        
        internal SharePointLibraryController(string siteCollection) : base(siteCollection) { }

        internal SharePointLibraryController(string siteCollection, string domain, string username, string password)
            : base(siteCollection, domain, username, password) { }
        
        protected bool DoesListAlreadyExist(ListsSoapClient client, string listName)
        {
            bool alreadyExist = false;

            XElement result = client.GetListCollection();
            XPathNavigator navigator = result.CreateNavigator();
            XPathNodeIterator iterator = navigator.SelectDescendants("List", "http://schemas.microsoft.com/sharepoint/soap/", false);
            while (iterator.MoveNext())
            {
                string title = iterator.Current.GetAttribute("Title", string.Empty);
                if (title.Equals(listName))
                {
                    alreadyExist = true;
                    break;
                }
            }

            return alreadyExist;
        }
        
        internal List<string> LoadLibraries(int templateId)
        {
            List<string> listList = new List<string>();

            XElement result = ListClient.GetListCollection();
            XPathNavigator navigator = result.CreateNavigator();
            XPathNodeIterator iterator = navigator.SelectDescendants("List", "http://schemas.microsoft.com/sharepoint/soap/", false);
            foreach (XPathNavigator current in iterator)
            {
                string title = current.GetAttribute("Title", string.Empty);
                string currentTemplate = current.GetAttribute("ServerTemplate", string.Empty);
                if (currentTemplate.Equals(templateId.ToString()))
                {
                    listList.Add(title);
                }
            }
            
            return listList;
        }

        protected List<string> CreateLibraries(string baseLibraryName, int templateId, int numberOfLibraries, bool deleteIfExist)
        {
            List<string> listList = new List<string>();

            DoContentGenerationItemsStarted(numberOfLibraries);

            bool cancel = false;
            for (int counter = 0; counter < numberOfLibraries; counter++)
            {
                string listName = baseLibraryName.Trim().Length > 0
                    ? baseLibraryName + counter.ToString()
                    : "Library LIB" + counter.ToString();

                string description = "Description for " + listName;

                bool exists = DoesListAlreadyExist(ListClient, listName);
                if (exists && deleteIfExist)
                {
                    DoContentGenerationItemChanging(listName, counter, numberOfLibraries, Core.ContentGeneratorAction.Deleting);
                    ListClient.DeleteList(listName);
                    exists = false;
                }

                if (!exists)
                {
                    cancel = DoContentGenerationItemChanging(listName, counter, numberOfLibraries, Core.ContentGeneratorAction.Creating);
                    if (cancel)
                        break;
                    ListClient.AddList(listName, description, templateId);
                    LibraryCreated(listName, counter);
                }

                listList.Add(listName);
            }

            DoContentGenerationItemsFinished();

            return listList;
        }

        internal void DeleteLibraries(List<string> librariesToDelete)
        {
            DoContentGenerationItemsStarted(librariesToDelete.Count);

            bool cancel = false;
            for (int counter = 0; counter < librariesToDelete.Count; counter++)
            {
                string listName = librariesToDelete[counter];

                if (DoesListAlreadyExist(ListClient, listName))
                {
                    cancel = DoContentGenerationItemChanging(listName, counter, librariesToDelete.Count, Core.ContentGeneratorAction.Deleting);
                    if (cancel)
                        break;
                    ListClient.DeleteList(listName);
                }
            }

            DoContentGenerationItemsFinished();
        }
    }
}
